package com.lpc.framework.search.util;

import java.util.Arrays;
import java.util.List;

import org.springframework.data.domain.Sort;
import org.springframework.util.StringUtils;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import com.google.common.collect.Lists;
import com.lpc.framework.search.SearchOperator;
import com.lpc.framework.search.Searchable;
import com.lpc.framework.search.filter.AndCondition;
import com.lpc.framework.search.filter.Condition;
import com.lpc.framework.search.filter.OrCondition;
import com.lpc.framework.search.filter.SearchFilter;

/**
 * @author jiangjinlong
 *
 */
public class SearchHelper {

    public void invokeExample(Example example, Searchable search) {
        if (!search.hasSearchFilter()) {
            if (example.getOredCriteria().isEmpty()) {
                example.createCriteria().andEqualTo("yn", 0);
            }
            return;
        }
        Criteria c = example.createCriteria().andEqualTo("yn", 0);
        Criteria or = null;
        for (SearchFilter searchFilter : search.getSearchFilters()) {

            if (searchFilter instanceof Condition) {
                getCriteria(c, searchFilter);
            } else if (searchFilter instanceof OrCondition) {
                if (or == null) {
                    or = example.createCriteria();
                }
                getCriteria(or, searchFilter);
            } else if (searchFilter instanceof AndCondition) {
                getCriteria(c, searchFilter);
            }

        }
        if (or != null) {
            example.or(or);
        }
    }
    
    //lpc
    public Example invokeExample1(Example example, Searchable search) {
        if (!search.hasSearchFilter()) {
            return example;
        }
        Criteria c = example.createCriteria();
        Criteria or = null;
        for (SearchFilter searchFilter : search.getSearchFilters()) {

            if (searchFilter instanceof Condition) {
                getCriteria(c, searchFilter);
            } else if (searchFilter instanceof OrCondition) {
                if (or == null) {
                    or = example.createCriteria();
                }
                getCriteria(or, searchFilter);
            } else if (searchFilter instanceof AndCondition) {
                getCriteria(c, searchFilter);
            }

        }
        if (or != null) {
            example.or(or);
        }
        return example;
    }
    
    private Criteria getCriteria(Criteria c, SearchFilter searchFilter) {
        Condition condition = (Condition) searchFilter;
        // 自定义条件
        String property = condition.getEntityProperty();
        String operatorStr = condition.getOperatorStr();
        if (!StringUtils.isEmpty(operatorStr)) {
            Object value = condition.getValue();
            // 操作符
            // 1、如果是自定义查询符号，则使用SearchPropertyMappings中定义的默认的操作符
            if (SearchOperator.eq.getSymbol().equals(operatorStr)) {
                c.andEqualTo(property, value);
            } else if (SearchOperator.gt.getSymbol().equals(operatorStr)) {
                c.andGreaterThan(property, value);
            } else if (SearchOperator.gte.getSymbol().equals(operatorStr)) {
                c.andGreaterThanOrEqualTo(property, value);
            } else if (SearchOperator.lt.getSymbol().equals(operatorStr)) {
                c.andLessThan(property, value);
            } else if (SearchOperator.lte.getSymbol().equals(operatorStr)) {
                c.andLessThanOrEqualTo(property, value);
            } else if (SearchOperator.in.getSymbol().equals(operatorStr)) {
                List<Object> list = Lists.newArrayList();
                list.addAll(Arrays.asList(String.valueOf(value).split(",")));
                c.andIn(property, list);
            } else if (SearchOperator.isNotNull.getSymbol().equals(operatorStr)) {
                c.andIsNotNull(property);
            } else if (SearchOperator.isNull.getSymbol().equals(operatorStr)) {
                c.andIsNull(property);
            } else if (SearchOperator.like.getSymbol().equals(operatorStr)) {
                c.andLike(property, "%" + String.valueOf(value) + "%");
            } else if (SearchOperator.ne.getSymbol().equals(operatorStr)) {
                c.andNotEqualTo(property, value);
            } else if (SearchOperator.notIn.getSymbol().equals(operatorStr)) {
                List<Object> list = Lists.newArrayList();
                list.add(String.valueOf(value).split(","));
                c.andNotIn(property, list);
            } else if (SearchOperator.notLike.getSymbol().equals(operatorStr)) {
                c.andNotLike(property, "%" + String.valueOf(value) + "%");
            } else if (SearchOperator.prefixLike.getSymbol().equals(operatorStr)) {
                c.andLike(property, "%" + String.valueOf(value));
            } else if (SearchOperator.prefixNotLike.getSymbol().equals(operatorStr)) {
                c.andNotLike(property, "%" + String.valueOf(value));
            } else if (SearchOperator.suffixLike.getSymbol().equals(operatorStr)) {
                c.andLike(property, String.valueOf(value) + "%");
            } else if (SearchOperator.suffixNotLike.getSymbol().equals(operatorStr)) {
                c.andNotLike(property, String.valueOf(value) + "%");
            }
        }
        return c;
    }

    public String prepareOrder(Searchable search) {
        StringBuffer sort = new StringBuffer(" ");
        if (search.hashSort()) {
            for (Sort.Order order : search.getSort()) {
                sort.append(String.format("%s %s, ", order.getProperty().split(":")[0], order.getDirection().name()
                        .toLowerCase()));
            }
            return sort.substring(0, sort.lastIndexOf(",")).toString();
        } else {
            return null;
        }

    }
}
